package lol.clann.bukkit.pluginboot.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lol.clann.clannboot.annotation.inject.Inject;
import lol.clann.clannboot.annotation.svc.PostInstance;
import lol.clann.clannboot.annotation.svc.Service;
import com.google.common.reflect.TypeToken;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers;
import org.bukkit.inventory.ItemStack;
import org.nutz.lang.Lang;

import java.io.IOException;
import java.util.Map;
import java.util.regex.PatternSyntaxException;

/**
 * @author pyz
 * @date 2018/8/12 下午5:32
 */
@Service
public class SerializeItemStack implements TypeSerializer<ItemStack> {

    @Inject
    private ObjectMapper objectMapper;

    @PostInstance
    private void init() {
        TypeSerializers.getDefaultSerializers().registerPredicate(typeToken -> ItemStack.class.isAssignableFrom(typeToken.getRawType()), this);
    }

    @Override
    public void serialize(TypeToken<?> typeToken, ItemStack itemStack, ConfigurationNode configurationNode) throws ObjectMappingException {
        try {
            ObjectNode node = objectMapper.valueToTree(itemStack);
            ConfigurationNode cNode = objectMapper.readValue(node.traverse(), ConfigurationNode.class);
            for (Map.Entry<Object, ? extends ConfigurationNode> objectEntry : cNode.getChildrenMap().entrySet()) {
                configurationNode.getNode(objectEntry.getKey()).setValue(objectEntry.getValue());
            }
        } catch (IOException e) {
            throw Lang.wrapThrow(e);
        }
    }

    public ItemStack deserialize(TypeToken<?> type, ConfigurationNode value) throws ObjectMappingException {
        try {
            ObjectNode node = objectMapper.valueToTree(value);
            try {
                return objectMapper.readValue(node.traverse(), ItemStack.class);
            } catch (IOException e) {
                throw Lang.wrapThrow(e);
            }
        } catch (PatternSyntaxException var4) {
            throw new ObjectMappingException(var4);
        }
    }

}
